<template>
	<view class="MakeAvatar" :style="{ height: webStyle.height }">
		<image class="bgi" :src="imgPath + 'login/Background.png'" mode=""></image>
		<view class="title-box" :style="{ 'padding-top': inf0Pt + 'vh' }">
			<view class="left" :style="{ 'margin-top': -0 + 'vh' }">
				<image class="back" @click="back" :src="imgPath + 'AICont/back-arrow.svg'" mode="widthFix"></image>
			</view>
			<view class="title" :style="{ 'margin-top': -0 + 'vh' }">定制数字人</view>
			<view class="right"><!-- 信息安全须知 --></view>
		</view>
		<view class="main-tabbar">
			<view class="tabbar-item" v-for="(item, index) in mainTabList" :key="index" @tap="mainTabInd = index">
				<view class="img">
					<image :style="{ width: item.id == 2 ? '86%' : '' }" :class="['icon', mainTabInd == index ? 'ac' : '']" :src="imgPath + 'MakeAvatar/' + item[mainTabInd == index ? 'imgAc' : 'img']" mode="widthFix"></image>
				</view>
				<view :class="['text', mainTabInd == index ? 'ac' : '']">{{ item.text }}</view>
			</view>
		</view>
		<view class="page1" v-if="mainTabInd == 0">
			<view class="content" @tap="openPopup('page1popup')">
				<template v-if="successRes1 && successRes1.tempVideoPath">
					<video :style="{ visibility: !page1popupShow && !uploadTipsShow ? 'visibility' : 'hidden', height: !page1popupShow && !uploadTipsShow ? '' : '0' }" @tap.stop="" class="video" object-fit="contain" :src="successRes1.tempVideoPath" controls></video>
				</template>
				<template v-else>
					<image class="icon" :src="imgPath + 'MakeAvatar/' + 'mainTab1.svg'" mode="widthFix"></image>
					<view class="text">点击拍摄训练视频</view>
				</template>
			</view>
			<view class="main-btns">
				<view class="btn style1" @tap="openPopup('page1popup')" v-if="successRes1 && successRes1.tempVideoPath">
					{{ "重新拍摄" }}
				</view>
				<view class="btn next-btn" @tap="nextStep">
					{{ "下一步" }}
				</view>
			</view>
		</view>
		<view class="page2" v-if="mainTabInd == 1">
			<view class="title">
				<view class="titleText">点击录制，朗读文案完成录音</view>
				<view class="subTitle">请找独立安静环境录制，语气和情感也会被克隆，录制时请按照期望的音色效果进行朗读。</view>
			</view>
			<view class="content" @taps="openPopup('page2popup')">
				<view class="read-text">
					{{ recordText }}
				</view>
				<view class="btns">
					<view class="btn" @tap.stop="randomText" v-if="0">
						<view class="icon" >
							<image class="pic" src="" mode=""></image>
						</view>
						<view class="txt">换一条</view>
					</view>
					<view class="" style="width: 2vw"></view>
					<!-- #ifndef APP -->
					<view class="btn" @tap.stop="$refs.tipsPopup.open()">
						<view class="icon" v-if="0">
							<image class="pic" src="" mode=""></image>
						</view>
						<view class="txt">上传音频</view>
					</view>
					<!-- #endif -->
					<!-- #ifdef APP -->
					<view class="btn" @tap.stop="toUploadPagePage()">
						<view class="icon" v-if="0">
							<image class="pic" src="" mode=""></image>
						</view>
						<view class="txt">上传音频</view>
					</view>
					<!-- #endif -->
				</view>
				<!-- <view v-if="successRes2 && successRes2.tempVideoPath" @tap.stop="">
					<audio :src="successRes2.tempVideoPath" :name="'训练音频'" controls></audio>
				</view>
				<template v-else>
					<image class="icon" :src="imgPath + 'MakeAvatar/' + 'mainTab1.svg'" mode="widthFix"></image>
					<view class="text">点击录制训练音频</view>
				</template> -->
			</view>
			<view class="record-box">
				<view style="width: 100%" v-if="successRes2 && successRes2.tempVideoPath" @tap.stop="">
					<!-- <audio :src="successRes2.tempVideoPath" :name="'我的录音'" controls></audio> -->
					<view class="audio-box">
						<view class="audio-cont">
							<view class="info">
								<view class="name">{{ recordingName || "录音文件.mp3" }}</view>
								<view class="time">{{ isNaN(audioCurrentTime) ? "00:00" : seconds2time(audioCurrentTime) }}/{{ seconds2time(audioDuration) }}</view>
							</view>
							<view class="btns">
								<view class="item del" @tap="delRecordingSrc">
									<image class="icon" :src="imgPath + 'index/del.svg'" mode="widthFix"></image>
								</view>
								<view class="item play" @tap="onPlayTap">
									<image class="icon" :src="imgPath + 'index/play' + (audioPlaying ? 'ing' : 'ed') + '_back.svg'" mode="widthFix"></image>
								</view>
							</view>
						</view>
						<view class="rate-box">
							<slider class="slider" :value="audioCurrentTime" :min="0" :max="audioDuration" disabled />
						</view>
					</view>
				</view>
				<template v-else>
					<view class="fft"></view>
					<view class="time">{{ seconds2time(recordingTime) == "00:00" ? "点击一下开始录音" : seconds2time(recordingTime) }}</view>
					<view class="record" @tap="recording">
						<view
							class="box-fff"
							:style="{
								width: recordingText == '结束' ? '76%' : '',
								height: recordingText == '结束' ? '76%' : ''
							}"
						></view>
						<view
							class="record-btn"
							:style="{
								'border-radius': recordingText == '结束' ? '1.5vw' : '',
								width: recordingText == '结束' ? '36%' : '',
								height: recordingText == '结束' ? '36%' : ''
							}"
						></view>
						<view class="circle-progress">
							<view class="circle-progress-outer"></view>
							<view class="left">
								<view class="circle-progress-fill" :style="{ transform: 'rotate(' + 180 + 'deg)' }"></view>
							</view>
							<view class="right">
								<view class="circle-progress-fill" :style="{ transform: 'rotate(' + 180 + 'deg)' }"></view>
							</view>
						</view>
					</view>
				</template>
			</view>
			<view class="main-btns">
				<view class="btn style1" @tap="delRecordingSrc" v-if="successRes2 && successRes2.tempVideoPath">
					{{ "重新录音" }}
				</view>
				<view class="btn next-btn" @tap="nextStep">
					{{ "下一步" }}
				</view>
			</view>
		</view>
		<view class="page3" v-if="mainTabInd == 2">
			<view class="main-form">
				<view class="form-item">
					<view class="label">
						<view class="text">数字人名称</view>
						<view class="subText">*</view>
					</view>
					<view class="box input-box">
						<input class="text" type="text" placeholder-class="nac" @input="(evnet) => replaceAvatarName(evnet)" :value="avatarName" :placeholder="'请输入数字人名称'" />
					</view>
				</view>
				<view class="form-item flex-box" style="flex: 1">
					<view class="label">
						<view class="text">身份授权</view>
						<view class="subText">*</view>
					</view>
					<view class="box upload-box" @tap="openPopup('page3popup')">
						<template v-if="successRes3 && successRes3.tempVideoPath && !submiting">
							<video v-if="!page2popupShow" @tap.stop="" class="video" object-fit="contain" :src="successRes3.tempVideoPath" controls></video>
						</template>
						<template v-else>
							<image class="icon" :src="imgPath + 'MakeAvatar/' + 'mainTab1.svg'" mode="widthFix"></image>
							<view class="text">点击拍摄授权视频</view>
						</template>
					</view>
				</view>
			</view>
			<view class="main-btns">
				<!-- <view class="btn style1" @tap="prevStep">上一步</view> -->
				<view class="btn style1" @tap="openPopup('page3popup')" v-if="successRes3 && successRes3.tempVideoPath">
					{{ "重新拍摄" }}
				</view>
				<view class="btn style2" @tap="submit">提交训练</view>
			</view>
		</view>
		<uni-popup ref="page1popup" type="bottom" background-color="#222224" @change="changjingPage1popupShow" border-radius="3vw 3vw 0 0">
			<view class="popup-view">
				<view class="popup-title">数字人拍摄教程</view>
				<view class="popup-cont">
					<view class="title">
						<view class="titleText">拍摄提示</view>
						<view class="subTitle">请在安静的环境下，保持镜头平视，吐字清晰的朗读文案</view>
					</view>
					<view class="photo-box">
						<image class="pic" src="https://ai.yainoo.com/video/appjpg/侧坐1.jpg"></image>
						<image class="pic" src="https://ai.yainoo.com/video/appjpg/挡嘴1.jpg" @taps="toPage('/pages/createVideo/createVideo')"></image>
						<image class="pic" src="https://ai.yainoo.com/video/appjpg/舔嘴1.jpg"></image>
						<!-- <image class="pic" src="https://ai.yainoo.com/video/appjpg/形象授权.jpg"></image> -->
						<image class="pic" src="https://ai.yainoo.com/video/appjpg/正确1.jpg"></image>
					</view>
					<!-- 	<view class="title">
						<view class="text">视频教程</view>
						<view class="subTitle"></view>
					</view> -->
					<view class="video-box">
						<image style="width: 100%" :src="imgPath + 'MakeAvatar/' + 'jiaocheng.png'" mode="widthFix"></image>
						<!-- <video v-if="page1popupShow" :show-center-play-btn="page1popupShow" id="page1popupVideo" class="video" :show-mute-btn="page1popupShow" src="https://ai.yainoo.com/video/小程序教程2.mp4" :controls="page1popupShow"></video> -->
					</view>
				</view>

				<view class="popup-btns">
					<view class="btn people-subBtn" @tap="showCamera('page1popup')">在线拍摄</view>
					<!-- <uni-file-picker ref="filePicker1" :value="filePickerVal" file-mediatype="video" mode="grid" :list-styles="imageStyles" @select="select">
						<view class="btn next-btn">本地视频</view>
					</uni-file-picker> -->
					<view class="btn next-btn style2" @tap="openUploadTips">手机相册上传</view>
				</view>
			</view>
		</uni-popup>
		<uni-popup ref="page2popup" type="bottom" background-color="#222224" @change="changjingPage2popupShow" border-radius="3vw 3vw 0 0">
			<view class="popup-view">
				<view class="popup-title">音频录制教程</view>
				<view class="popup-cont">
					<view class="title">
						<view class="titleText">录制提示</view>
						<view class="subTitle">请在安静的环境下，吐字清晰的朗读文案</view>
					</view>
					<view class="photo-box">
						<view class="pos-box">
							<image class="pic style2" src="https://ai.yainoo.com/video/appjpg/形象授权压缩.jpg" mode="widthFix" style="opacity: 0"></image>
							<view class="pos-text" style="font-size: 4vw; overflow: auto">
								大家好，我现在虽然不能脱稿录制，正在念提词器，但是也可以生成 不错的数字人。只要咱们上传的录制视频能满足:取景构图优美、动作表情自 然、口齿清晰、表达流畅，最终的效果就不会太差。如果第一次念提词器有点 不顺畅，也别担心不妨花几分钟时间，多试验练习，找到自己最佳的状态。面
								对人工智能时代的到来，我相信，我的探索和实践，会帮助我超越那些焦虑、 观望但不行动的人，让我在未来的发展竞争中打破信息差，获得更多的机遇和 成果。
							</view>
						</view>
					</view>
				</view>
				<view class="popup-btns">
					<view class="btn people-subBtn" @tap="recording">{{ recordingText }}录音</view>
					<!-- <uni-file-picker ref="filePicker1" :value="filePickerVal" file-mediatype="video" mode="grid" :list-styles="imageStyles" @select="select">
						<view class="btn next-btn">本地视频</view>
					</uni-file-picker> -->
				</view>
			</view>
		</uni-popup>
		<uni-popup ref="page3popup" type="bottom" background-color="#222224" border-radius="3vw 3vw 0 0">
			<view class="popup-view">
				<view class="popup-title">授权视频拍摄教程</view>
				<view class="popup-cont">
					<view class="photo-box">
						<view class="pos-box">
							<image class="pic style2" src="https://ai.yainoo.com/video/appjpg/形象授权压缩.jpg" mode="widthFix"></image>
							<view class="pos-text">您还需要录制一段形象声音授权视频，请按提示词里面的文案跟读</view>
						</view>
					</view>
				</view>
				<view class="popup-btns">
					<view class="btn people-subBtn" @tap="showCamera('page3popup')">在线拍摄</view>
					<!-- <uni-file-picker ref="filePicker1" :value="filePickerVal" file-mediatype="video" mode="grid" :list-styles="imageStyles" @select="select">
						<view class="btn next-btn">本地视频</view>
					</uni-file-picker> -->
					<view class="btn next-btn style2" @tap="openUploadTips">手机相册上传</view>
				</view>
			</view>
		</uni-popup>
		<uni-popup ref="tipsPopup" type="dialog">
			<uni-popup-dialog mode="base" title="温馨提示" :confirmText="'确定'" :showClose="true" @confirm="wx_uploadFile">
				<!-- #ifdef MP-WEIXIN -->
				<view class="tips" style="color: #000">从微信聊天记录选择{{ "音频文件" }}</view>
				<!-- #endif -->

				<!-- #ifdef H5 -->
				<view class="tips" style="color: #000">从系统文件选择{{ "音频文件" }}</view>
				<!-- #endif -->
			</uni-popup-dialog>
		</uni-popup>
		<uni-popup ref="uploadTips" type="dialog" @change="changeUploadTipsShow">
			<uni-popup-dialog mode="base" title="温馨提示" confirmText="手机相册上传" :showClose="true" @confirm="selectVideo('page1popup')">
				<view class="uploadTips">
					<view class="">本地视频要求:</view>
					<view class="">文件格式: MP4/MOV</view>
					<view class="">视频长度: 1分钟内</view>
					<view class="">文件大小: 小于100MB</view>
					<view class="">分辨率: 1080P</view>
					<view class="">视频尺寸: 9:16</view>
				</view>
			</uni-popup-dialog>
		</uni-popup>
		<view style="position: fixed; z-index: 999;width: 100vw;height: 100vh;left: 0;top: 0;" v-if="pageLoading">
			<!-- #ifndef APP -->
			<PageLoading :tips="pageLoadingTips" mode="view"></PageLoading>
			<!-- #endif -->
			<!-- #ifdef APP -->
			<PageLoading :tips="pageLoadingTips"></PageLoading>
			<!-- #endif -->
		</view>

		<!-- #ifdef H5 -->
		<RecorderCore ref="RecorderCore" v-show="0"></RecorderCore>
		<uni-popup ref="RecorderPopup" type="dialog">
			<uni-popup-dialog mode="base" title="温馨提示" :confirmText="'确定'" :showClose="true">
				<view class="tips" style="color: #000">{{ RecorderTips }}</view>
			</uni-popup-dialog>
		</uni-popup>
		<!-- #endif -->
	</view>
</template>

<script>
import { tools } from "../../utils/util";
import PageLoading from "@/components/PageLoading/PageLoading.vue";
import * as api from "@/api/home.js";
const Mp3 = require("js-mp3");

// #ifdef H5
import axios from "axios";
import RecorderCore from "@/components/RecorderCore/RecorderCore.vue";
//  #endif

export default {
	name: "MakeAvatar",
	data() {
		return {
			imgPath: tools.imgPath,
			inf0Pt: 0,
			systemInfo: {},
			webStyle: {
				height: ""
			},
			filePickerVal: [],
			imageStyles: {
				width: "0px",
				height: "0px",
				// 是否显示边框
				border: false,
				// 是否显示分隔线
				dividline: false,
				// 线条样式
				borderStyle: {
					width: 1,
					color: "blue",
					radius: 2
				}
			},
			pageLoading: false,
			pageLoadingTips: "",
			page1popupShow: false,
			page2popupShow: false,
			uploadTipsShow: false,
			avatarName: "",
			mainTabInd: 0,
			mainTabList: [
				{
					id: 1,
					img: "mainTab1.svg",
					imgAc: "mainTab1-ac.svg",
					text: "克隆形象"
				},
				{
					id: 2,
					img: "luyin-big.svg",
					imgAc: "luyin-big-ac.svg",
					text: "克隆声音"
				},
				{
					id: 3,
					img: "mainTab2.svg",
					imgAc: "mainTab2-ac.svg",
					text: "身份认证"
				}
			],
			uploadName: "",
			successRes1: null,
			successRes2: null,
			successRes3: null,
			submiting: false,
			audioContext: null,
			audioCurrentTime: 0,
			audioDuration: 0,
			audioPlaying: false,
			recordingTimer: null,
			recordingTime: 0,
			recordingText: "开始",
			recordingSrc: "",
			recordingPlaying: false,
			recordingName: "",
			recorderManager: null,
			recordText: "",
			RecorderTips: "",
			mediaRecorder: {
				state: ""
			},
			lineArr: [],
			audioWebCtx: null,
			analyser: null
		};
	},
	methods: {
		// web上传页面
		toUploadPagePage() {
			this.toPage("/pages/uploadPage/uploadPage");
		},
		// 随机录音文本
		randomText() {
			let ind = tools.randomNum(0, tools.contList.length - 1);
			// this.recordText = tools.contList[ind].text;
			this.recordText = "一切都会好起来的，即使不是在今天，总有一天会的。非让现实给你一巴掌，你才知道社会有多虚伪。人生不过如此，你永远是自己的主角，加油吧！";
		},
		// 录音器初始化
		initRecorderManager() {
			this.randomText();
			this.recorderManager = uni.getRecorderManager();
			// #ifdef MP-WEIXIN
			if (!this.audioWebCtx) {
				this.audioWebCtx = wx.createWebAudioContext();
				this.analyser = this.audioWebCtx.createAnalyser();
			}
			// #endif
			this.recorderManager.onStart((res) => {
				this.recordingTime = 0;
				const start = Date.now();
				this.recordingTimer = setInterval(() => {
					const millis = Date.now() - start;
					// console.log(`seconds elapsed = ${Math.floor(millis / 1000)}`)
					this.recordingTime = millis / 1000;
					// expected output: seconds elapsed = 2
				}, 1000 / 60);
				this.recordingText = "结束";
				console.log("this.recorderManager.onStart", res);
			});
			this.recorderManager.onPause((res) => {
				console.log("this.recorderManager.onPause", res);
			});
			this.recorderManager.onStop(async (res) => {
				console.log("this.recorderManager.onStop", res);
				// {
				// 	"duration": 6800,
				// 	"tempFilePath": "wxfile://tmp_3cac9a828e3c509cda85e2368936ecd216185b380cf12322.mp3",
				// 	"fileSize": 110340
				// }
				this.audioDuration = res.duration / 1000;
				uni.showLoading({
					title: "提交中..."
				});
				let name = "recordFile";
				let tempFilePath = res.tempFilePath;
				let ossData = await api.postOSS({
					reqType: "",
					matName: name,
					payLoad: {}
				});
				console.log(tempFilePath);
				let ossRes = await this.getOSSApi_new(ossData, tempFilePath, name);
				uni.hideLoading();
				this.recordingText = "开始";
				if (ossRes?.src) {
					this.recordingSrc = ossRes.src;
					this.successRes2 = {
						tempVideoPath: ossRes.src
					};
					this.audioContext.src = ossRes.src;
					this.recordingName = "";
					this.$refs.page2popup.close();
				}
			});
			let nextDecode = true;
			this.recorderManager.onFrameRecorded((res) => {
				return;
				const { frameBuffer } = res;
				// const intArray = new Uint8Array(frameBuffer);
				// this.intArray = [...intArray];
				// const amplitude = Math.max(...intArray); // 计算当前帧的振幅
				// console.log(this.intArray, amplitude);
				if (nextDecode) {
					console.log(nextDecode, frameBuffer, 12311);
					nextDecode = false;
					this.audioWebCtx.decodeAudioData(
						frameBuffer,
						(buffer) => {
							let source = audioWebCtx.createBufferSource();
							console.log(source);
							nextDecode = true;
							return;
							source.buffer = buffer;

							source.connect(analyser);

							source.start();

							let n = new Uint8Array(analyser.frequencyBinCount);

							analyser.getByteTimeDomainData(n);

							let i = 0,
								r = 0,
								s = 0;

							r = Math.max.apply(null, n);

							s = Math.min.apply(null, n);

							i = (r - s) / 128;

							i = Math.round((i * 100) / 2);

							i = i > 100 ? 100 : i;

							console.log("soundIntensity", listener.isLastFrame ? 0 : i);
						},
						(err) => {
							console.error("decodeAudioData fail", err);
							nextDecode = true;
						}
					);
				}

				// this.frameBuffer = Array.from(res.frameBuffer);
			});
			this.recorderManager.onError((res) => {
				console.log("this.recorderManager.onError", res);
				tools.easyToast(res.errMsg);
				if (this.recordingTimer) {
					clearInterval(this.recordingTimer);
					this.recordingTimer = null;
				}
			});
		},
		// 音频播放器初始化
		initAudioContext() {
			this.audioContext = uni.createInnerAudioContext();
			this.audioContext.onCanplay((res) => {
				// if (!this.audioContext.duration || this.audioContext.duration == Infinity) {
				// 	let tempCtx = uni.createInnerAudioContext();
				// 	tempCtx.volume = 0;
				// 	tempCtx.autoplay = true;
				// 	tempCtx.src = this.audioContext.src;
				// 	tempCtx.onTimeUpdate((ctxres) => {
				// 		console.log("tempCtx.onTimeUpdate", tempCtx.duration, ctxres);
				// 		if (tempCtx.duration && tempCtx.duration != Infinity) {
				// 			console.log("tempCtx.onCanplay1-1", tempCtx.duration);
				// 			this.audioDuration = tempCtx.duration;
				// 			tempCtx.stop();
				// 		} else {
				// 			console.log("tempCtx.onCanplay1-2", tempCtx.duration);
				// 		}
				// 	});
				// 	tempCtx.onStop(() => {
				// 		tempCtx.destroy();
				// 	});
				// 	tempCtx.onEnded(() => {
				// 		tempCtx.destroy();
				// 	});
				// } else {
				// 	console.log("this.audioContext.onCanplay2", this.audioContext.duration);
				// 	this.audioDuration = this.audioContext.duration;
				// }
			});
			this.audioContext.onPlay((res) => {
				this.audioPlaying = true;
				console.log("this.audioContext.onPlay", res);
			});
			this.audioContext.onPause((res) => {
				this.audioPlaying = false;
				console.log("this.audioContext.onPause", res);
			});
			this.audioContext.onEnded((res) => {
				this.audioPlaying = false;
				this.audioContext.seek(0);
				this.audioCurrentTime = 0;
				console.log("this.audioContext.onEnded", res);
			});
			this.audioContext.onStop((res) => {
				this.audioPlaying = false;
				this.audioContext.seek(0);
				this.audioCurrentTime = 0;
				console.log("this.audioContext.onStop", res);
				if (!this.successRes2?.tempVideoPath) {
					this.audioContext.destroy();
					this.audioContext = null;
				}
			});
			this.audioContext.onSeeking((res) => {
				console.log("this.audioContext.onSeeking", this.audioContext.currentTime);
			});
			this.audioContext.onTimeUpdate((res) => {
				if (this.audioPlaying) {
					this.audioCurrentTime = this.audioContext.currentTime;
					console.log("this.audioContext.onTimeUpdate", this.audioContext.currentTime);
				}
			});
		},
		// 获取音频时长
		getAudioTime(src) {
			console.log("获取音频时长");
			this.audioDuration = 0;
			uni.showLoading({
				title: "请稍后..."
			});
			let tempCtx = uni.createInnerAudioContext();
			tempCtx.volume = 0;
			tempCtx.autoplay = true;
			tempCtx.src = src;
			tempCtx.onTimeUpdate((ctxres) => {
				console.log("tempCtx.onTimeUpdate", tempCtx.duration, ctxres);
				if (tempCtx.duration && tempCtx.duration != Infinity) {
					console.log("tempCtx.onCanplay1-1", tempCtx.duration);
					this.audioDuration = tempCtx.duration;
					tempCtx.stop();
				} else {
					console.log("tempCtx.onCanplay1-2", tempCtx.duration);
				}
			});
			tempCtx.onStop(() => {
				uni.hideLoading();
				if (tempCtx) {
					tempCtx.destroy();
					tempCtx = null;
				}
			});
			tempCtx.onEnded(() => {
				uni.hideLoading();
				if (tempCtx) {
					tempCtx.destroy();
					tempCtx = null;
				}
			});
			tempCtx.onError((err) => {
				console.log(err);
				tools.easyToast(err);
				if (tempCtx) {
					tempCtx.destroy();
					tempCtx = null;
				}
			});
		},
		// 录音
		async recording_H5() {
			console.log("recording_H5");
			//录音
			const that = this;

			if (that.recordingPlaying) {
				this.stopPlaying();
			}
			if (that.mediaRecorder.state != "recording") {
				this.RecorderTips = "";
				//开始录音
				let flag = await that.$refs.RecorderCore.recStart();
				if (!flag) {
					console.log(that.$refs.RecorderCore.logs);
					this.RecorderTips = that.$refs.RecorderCore.logs[0].msg;

					this.$refs.RecorderPopup.open();
					this.mediaRecorder.state = "";
					return;
				}
				let nowTime = new Date().getTime();
				that.recordingTimer = setInterval(() => {
					that.recordingTime = (new Date().getTime() - nowTime) / 1000;

					// that.recordingTime = tools.seconds2time(that.$refs.RecorderCore.duration / 1000);
				}, 1000 / 60);
				that.mediaRecorder.state = "recording";
				that.recordingText = "结束";
			} else {
				//停止录音
				let flag = await that.$refs.RecorderCore.recStop();
				if (!flag) return;
				clearInterval(that.recordingTimer);
				that.recordingTimer = null;
				that.mediaRecorder.state = "";
				that.recordingText = "开始";
				that.audioDuration = that.recordingTime;
				let blob = this.$refs.RecorderCore.logs[0].res.blob;
				let tempSrc = URL.createObjectURL(blob);
				console.log("停止录音");
				let matterValue = await tools.setVideoSrc(tempSrc);
				let name = new Date().getTime();
				let fileOfBlob = new File([blob], name, {
					type: "audio/wav"
				});
				let ossData = await api.postOSS({
					reqType: "mat_audio",
					matName: name,
					payLoad: { matterValue: matterValue }
				});
				let res = await this.getOSSApi_new_H5(ossData, fileOfBlob, name);
				console.log(res);
				// let res = await that.getOSSApi(fileOfBlob, name);
				if (res?.src) {
					that.recordingSrc = res.src;
					that.audioName = "我的录音";
					that.successRes2 = {
						tempVideoPath: res.src
					};
					that.audioContext.src = res.src;
					that.recordingName = "";
				} else {
					that.recordingSrc = "";
					that.audioContext.src = "";
				}
			}
		},

		// 录音
		async recording() {
			// #ifdef H5
			this.recording_H5();
			return;
			//  #endif
			const that = this;
			if (!that.recordingTimer) {
				let next = await new Promise(async (next) => {
					// #ifdef APP
					let statusCode = await tools.app_permision.requestAndroidPermission("android.permission.RECORD_AUDIO");
					next(statusCode == 1);
					// #endif
					// #ifdef MP-WEIXIN
					uni.authorize({
						scope: "scope.record",
						success() {
							next(true);
						},
						fail() {
							next(false);
						}
					});
					// #endif
					// #ifdef H5
					next(true);
					// #endif
				});
				if (!next) {
					tools.easyToast("未授权录音！");
					return;
				}

				this.recordingText = "结束";
				//开始录音
				that.recordingSrc = "";
				that.audioDuration = 0;

				that.recorderManager.start({
					// duration: 60000,
					// format: "mp3",
					// sampleRate: 22050,
					// numberOfChannels: 1,
					// encodeBitRate: 124000,
					// frameSize: 0.1

					// duration: 23000,
					// sampleRate: 16000, //采样率
					// numberOfChannels: 1, //录音通道数
					// encodeBitRate: 96000, //编码码率
					// format: "mp3", //音频格式，有效值 aac/mp3
					// frameSize: 1,

					format: "mp3",
					duration: 23000,
					numberOfChannels: 1,
					frameSize: 0.1, //这里设置的太大，返回切片时会有问题，官方的说法：这里是大小/kb，满足设定的大小会回调一次切片
					sampleRate: 44100, // 采样率， 不能过低， js-mp3 不能解析
					encodeBitRate: 64000 // 编码码率
				});
			} else {
				this.recordingText = "开始";
				that.recorderManager.stop();
				clearInterval(that.recordingTimer);
				that.recordingTimer = null;
			}
		},
		// 播放
		onPlayTap() {
			if (!this.audioPlaying) {
				this.audioContext.play();
			} else {
				this.audioContext.pause();
			}
		},
		// 删除
		delRecordingSrc() {
			this.successRes2.tempVideoPath = "";
			this.recordingSrc = "";
			this.recordingTime = 0;
		},
		// 获取上传状态
		select(e) {
			console.log("选择文件：", e);
			this.successRes1 = {
				tempVideoPath: e.tempFilePaths[0]
			};
			this.$refs.filePicker1.clearFiles();
		},
		// 获取上传进度
		progress(e) {
			console.log("上传进度：", e);
		},

		// 上传成功
		success(e) {
			console.log("上传成功");
		},

		// 上传失败
		fail(e) {
			console.log("上传失败：", e);
		},
		// res数据初始化
		initRes() {
			let successRes = null;
			let type = null;
			["tempRecordVideoRes1", "tempRecordVideoRes2", "tempRecordVideoRes3"].map((e, i) => {
				let res = uni.getStorageSync(e);
				if (!res) return;
				type = i + 1;
				successRes = res;
				this["successRes" + type] = successRes || {};
				// uni.removeStorageSync(e);
			});
			// #ifdef APP
			let uploadPageCb = uni.getStorageSync("uploadPageCb");
			console.log(uploadPageCb[0].type);
			if (uploadPageCb[0].type == "submitSuccess") {
				this.successRes2 = {
					tempVideoPath: uploadPageCb[0].onlineSrc
				};
				this.recordingName = uploadPageCb[0].fileName;
				uploadPageCb[0].type = "submitSuccess-ok";
				uni.setStorageSync("uploadPageCb", uploadPageCb);
			}
			// #endif
		},

		// 获取系统info
		initSystemInfo(isUpdate = true) {
			console.log(this.basePath);
			const that = this;
			return new Promise((resolve, reject) => {
				uni.getSystemInfo({
					success(payload) {
						if (isUpdate) {
							that.systemInfo = payload;
							that.webStyle.height = `${that.systemInfo.windowHeight}px`;
							console.log("initSystemInfo", that.systemInfo);
							switch (that.systemInfo.uniPlatform) {
								case "web":
									that.inf0Pt = 4.5;
									break;
								case "app":
									that.inf0Pt = 4.5;
									break;
								case "mp-weixin":
									that.inf0Pt = 9.6;
									break;
							}
						}
						resolve(payload);
					}
				});
			});
		},

		// 修改数字人名称
		replaceAvatarName(event) {
			this.avatarName = event.target.value;
		},
		// 选择本地视频
		selectVideo(refName) {
			const that = this;
			this.$refs.uploadTips.close();
			uni.chooseVideo({
				sourceType: ["album"],
				maxDuration: 30,
				compressed: false,
				camera: "front",
				success(res) {
					console.log("选择本地视频", res);
					// res => {
					// 	"duration": 4,
					// 	"size": 203949,
					// 	"tempFilePath": "wxfile://tmp_7901d4c0d5f618d44023e110ee28986df8edd682a9a4659e.mp4",
					// 	"width": 540,
					// 	"errMsg": "chooseVideo:ok",
					// 	"height": 960
					// }
					console.log((res.width / res.height).toFixed(4) != 9 / 16, (res.width / res.height).toFixed(4), 9 / 16);
					// if (res.duration > 30) {
					// 	return tools.easyToast("视频时长超过30秒,请重新选择文件!");
					// }
					// if (res.duration < 25) {
					// 	return tools.easyToast("视频时太短,请重新选择文件!");
					// }
					// if (res.width > 720 || res.height > 1280) {
					// 	return tools.easyToast("视频分辨率不能大于720P!");
					// }
					// if ((res.width / res.height).toFixed(4) != 9 / 16) {
					// 	return tools.easyToast("视频比例必须为9:16!");
					// }
					that[`successRes${+that.mainTabInd + 1}`] = {
						tempVideoPath: res.tempFilePath
					};

					that.$refs[refName]?.close();
					let videoCtx = uni.createVideoContext(refName + "Video");
					videoCtx.pause();
				},
				fail(err) {
					console.log(err);
					tools.easyToast("选择文件失败，请重新选择!");
				}
			});
		},
		// 下一步
		nextStep() {
			if (this.mainTabInd == 0 && !this.successRes1?.tempVideoPath) {
				this.openPopup("page1popup");
			} else if (this.mainTabInd == 1 && !this.successRes2?.tempVideoPath) {
				tools.easyToast("请完成录音!");
				// this.openPopup("page2popup");
			} else if (this.mainTabInd == 2 && !this.successRes3?.tempVideoPath) {
				this.openPopup("page3popup");
			} else {
				this.mainTabInd = this.mainTabInd + 1;
			}
		},

		// 上一步
		prevStep() {
			this.mainTabInd = this.mainTabInd - 1;
		},
		//上传文件api
		async getOSSApi_new_H5(ossData, file, name) {
			const that = this;
			let res = ossData;

			function getUUID() {
				let keyStr = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
				keyStr = "xxxxxxxx-6xxx";
				return keyStr.replace(/[xy]/g, (c) => {
					return (c === "x" ? (Math.random() * 16) | 0 : "r&0x3" | "0x8").toString(16);
				});
			}
			const formData = new FormData();
			let url_name = "https://alleymall.oss-cn-guangzhou.aliyuncs.com";
			let key = res.data.dir + "/" + getUUID() + name;
			formData.append("policy", res.data.policy);
			formData.append("signature", res.data.signature);
			formData.append("ossaccessKeyId", res.data.accessid);
			formData.append("key", key);
			formData.append("dir", res.data.dir);
			formData.append("host", res.data.host);
			formData.append("expire", res.data.expire);
			formData.append("callback", res.data.callback);
			// formData.append('type', res.data.callback)
			formData.append("file", file);

			return axios
				.post(url_name, formData, {
					headers: {
						"Content-Type": "multipart/form-data"
					}
				})
				.then((response) => {
					let src = url_name + "/" + key;
					// console.log(src);
					// that.audioPlayerSrc = src;
					// console.log(response);
					return {
						...response,
						src
					};
				})
				.catch((error) => {
					console.log(error);
				});
		},

		// oss上传文件
		getOSSApi_new(ossData, file, name, uploadName = "") {
			console.log("oss", ossData, file, name);
			const that = this;
			let res = ossData;
			function getUUID() {
				let keyStr = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
				keyStr = "xxxxxxxx-6xxx";
				return keyStr.replace(/[xy]/g, (c) => {
					return (c === "x" ? (Math.random() * 16) | 0 : "r&0x3" | "0x8").toString(16);
				});
			}
			let url_name = "https://alleymall.oss-cn-guangzhou.aliyuncs.com";
			let key = res.data.dir + "/" + getUUID() + name;
			let opt = {
				url: url_name,
				filePath: file,
				name: "file",
				timeout: 1000 * 60 * 10,
				formData: {
					policy: res.data.policy,
					signature: res.data.signature,
					ossaccessKeyId: res.data.accessid,
					key: key,
					dir: res.data.dir,
					host: res.data.host,
					expire: res.data.expire,
					callback: res.data.callback
				}
			};
			console.log(opt);
			return new Promise((next) => {
				let task = uni.uploadFile({
					...opt,
					success: (uploadFileRes) => {
						let src = url_name + "/" + key;
						// console.log(src);
						// that.audioPlayerSrc = src;
						// console.log(response);
						next({ ...uploadFileRes, src });
					},
					fail(err) {
						console.err(err);
						next(false);
						this.submiting = false;
					}
				});
				task.onProgressUpdate((uploadFileRes) => {
					console.log("task.onProgressUpdate", uploadFileRes);
					if (uploadName) {
						that.pageLoadingTips = `${uploadName}上传中  ${uploadFileRes.progress}%`;
					}
					if (uploadFileRes.progress == 100) {
						let src = url_name + "/" + key;
						// next({ ...uploadFileRes, src });
					}
				});
			});
		},
		//上传文件api
		async getOSSApi(ossData, file, name) {
			const that = this;
			let res = ossData;

			function getUUID() {
				let keyStr = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
				keyStr = "xxxxxxxx-6xxx";
				return keyStr.replace(/[xy]/g, (c) => {
					return (c === "x" ? (Math.random() * 16) | 0 : "r&0x3" | "0x8").toString(16);
				});
			}
			const formData = new FormData();
			let url_name = "https://alleymall.oss-cn-guangzhou.aliyuncs.com";
			let key = res.data.dir + "/" + getUUID() + name;
			formData.append("policy", res.data.policy);
			formData.append("signature", res.data.signature);
			formData.append("ossaccessKeyId", res.data.accessid);
			formData.append("key", key);
			formData.append("dir", res.data.dir);
			formData.append("host", res.data.host);
			formData.append("expire", res.data.expire);
			formData.append("callback", res.data.callback);
			// formData.append('type', res.data.callback)
			formData.append("file", file);

			return axios
				.post(url_name, formData, {
					headers: {
						"Content-Type": "multipart/form-data"
					}
				})
				.then((response) => {
					let src = url_name + "/" + key;
					// console.log(src);
					// that.audioPlayerSrc = src;
					// console.log(response);
					return {
						...response,
						src
					};
				})
				.catch((error) => {
					console.log(error);
				});
		},

		// 提交
		async submit() {
			if (!this.successRes1?.tempVideoPath) {
				return tools.easyToast("请补充训练视频!");
			}
			if (!this.successRes2?.tempVideoPath) {
				return tools.easyToast("请补充训练音频!");
			}
			if (!this.successRes3?.tempVideoPath) {
				return tools.easyToast("请补充授权视频!");
			}
			if (!this.avatarName) {
				return tools.easyToast("请输入数字人名称!");
			}
			if (this.submiting) return;
			this.submiting = true;
			this.pageLoadingTips = "提交中...";
			this.pageLoading = true;
			let video = await new Promise(async (next) => {
				let name = this.avatarName + "训练视频" + tools.createID();
				let ossData = await api.postOSS({
					reqType: "",
					matName: name,
					payLoad: {}
				});

				if (this.successRes1.tempVideoPath.includes("https://alleymall.oss-cn-guangzhou.aliyuncs.com")) {
					let res = {
						src: this.successRes1.tempVideoPath
					};
					next(res.src);
				} else {
					let res = await this.getOSSApi_new(ossData, this.successRes1.tempVideoPath, name, "训练视频");
					next(res.src);
				}
			});
			this.pageLoadingTips = "提交中...";
			console.log({ video });
			let rootvideo = await new Promise(async (next) => {
				let name = this.avatarName + "授权视频" + tools.createID();
				let ossData = await api.postOSS({
					reqType: "",
					matName: name,
					payLoad: {}
				});
				let res = await this.getOSSApi_new(ossData, this.successRes3.tempVideoPath, name, "授权视频");
				next(res.src);
			});
			this.pageLoadingTips = "提交中...";
			console.log({ rootvideo });
			// let rootvideo = await new Promise(async (next) => {
			// 	let name = this.avatarName + "授权视频" + tools.createID();
			// 	let ossData = await api.postOSS({
			// 		reqType: "",
			// 		matName: name,
			// 		payLoad: {}
			// 	});
			// 	uni.showLoading({
			// 		title: "提交中..."
			// 	});
			// 	let res = await this.getOSSApi_new(ossData, this.successRes3.tempVideoPath, name);
			// 	next(res.src);
			// });
			let image = await new Promise(async (next) => {
				let name = this.avatarName + "封面" + tools.createID();
				let ossData = await api.postOSS({
					reqType: "",
					matName: name,
					payLoad: {}
				});
				this.pageLoadingTips = "上传中...";
				let inputVal = this.successRes1.tempThumbPath;
				if (inputVal) {
					let res = await this.getOSSApi_new(ossData, inputVal, name);
					next(res.src);
				} else {
					let res = await api.processingVideo({ url: video, num: 1 });
					console.log("获取视频第一帧", res);
					if (!res) return tools.easyToast("提交失败！tips:" + "feng-fail");
					next(res.data.replace(/\n/g, ""));
				}
			});
			let audio = this.successRes2.tempVideoPath;
			let sand = {
				video: video,
				image: image /* || "https://alleymall.oss-cn-guangzhou.aliyuncs.com/2024-04-26/8f525f82-6880fengmian.png" */,
				rootvideo: rootvideo,
				audio: audio,
				modename: this.avatarName
			};
			console.log("MakeAvatarSubmit", sand);
			this.pageLoading = false;

			uni.showLoading({
				title: "提交中"
			});
			let res = await api.materialUpload(sand);
			uni.hideLoading();
			if (!res) return (this.submiting = false);
			console.log("materialUpload", res);
			this.pageLoading = false;
			tools.easyToast("提交成功!");
			uni.setStorageSync("toHome", {
				footerBarListAc: 2
			});
			uni.reLaunch({
				url: "/pages/index/index"
			});
		},

		// 打开弹出层
		async openPopup(refName) {
			// 通过组件定义的ref调用uni-popup方法 ,如果传入参数 ，type 属性将失效 ，仅支持 ['top','left','bottom','right','center']
			this.$refs[refName]?.open("bottom");
			console.log("打开弹出层", refName + "Video");
			await new Promise((wait) => setTimeout(wait), 500);
			let videoCtx = uni.createVideoContext(refName + "Video", this);
			await new Promise((wait) => setTimeout(wait), 500);
			console.log("视频播放");
			videoCtx.play();
		},

		// pagePopup显隐
		changjingPage1popupShow(val) {
			this.page1popupShow = val.show;
		},
		// pagePopup显隐
		changjingPage2popupShow(val) {
			this.page2popupShow = val.show;
		},
		// UploadTipsp显隐
		changeUploadTipsShow(val) {
			this.uploadTipsShow = val.show;
		},
		// 显示上传要求
		openUploadTips() {
			let mainTabInd = +this.mainTabInd + 1;
			this.$refs[`page${mainTabInd}popup`].close();
			this.$refs.uploadTips.open();
		},
		// wx小程序上传音频
		async wx_uploadFile() {
			const that = this;
			let extension = ["wav", "mp3", "aac", "m4a", "ogg", "3gpp"];
			extension = extension.reduce((p, e) => {
				p.push(e);
				p.push(e.toLocaleUpperCase());
				return p;
			}, []);

			let res = await new Promise((next) => {
				// #ifdef H5
				uni.chooseFile({
					count: 1, //默认100
					extension: extension,
					success: function (res) {
						next(res);
					},
					fail(err) {
						console.error(err);
						next(null);
					}
				});
				// #endif

				// #ifdef MP-WEIXIN
				uni.chooseMessageFile({
					count: 1, //默认100
					type: "file",
					extension: extension,
					success: async (res) => {
						next(res);
					},
					fail(err) {
						console.error(err);
						next(null);
					}
				});
				// #endif
			});
			if (!res) {
				return tools.easyToast("上传失败2!");
			}
			let file = res.tempFiles[0];
			console.log("选择音频文件", res);
			// {
			// 	"errMsg": "chooseMessageFile:ok",
			// 	"tempFiles": [{
			// 		"path": "wxfile://tmp_31dc92a076e8445ad5c1157cffed8ced9d583501207d8e07.mp3",
			// 		"name": "Go_Beyond_Andy.mp3",
			// 		"size": 10286911,
			// 		"type": "file",
			// 		"time": 1716533118,
			// 	}],
			// }
			that.recordingName = file.name;
			// let condition = extension.some((e) => file.name.includes(e));
			// if (!condition) {
			// 	return tools.easyToast("请选择音频文件！");
			// }
			let name = file.name.replace(/[^\u4e00-\u9fa5a-zA-Z0-9\.]+/g, "");
			// if (!/^[\u4e00-\u9fa5a-zA-Z0-9\.\-]+$/.test(name)) {
			// 	return tools.easyToast("文件名不能包含符号，只能是文字或数字");
			// }
			if (file.size / 1024 / 1024 > that.uploadFileSize) {
				return tools.easyToast(`文件大小超过${that.uploadFileSize}M!`);
			}
			let ossData = await api.postOSS({
				reqType: "",
				matName: name,
				payLoad: {}
			});
			let ossRes = await that.getOSSApi_new(ossData, file.path, name);
			if (!ossRes) {
				tools.easyToast("上传失败！");
				return;
			}
			console.log("上传音频", ossRes);
			that.recordingSrc = ossRes.src;
			that.audioName = name;
			that.successRes2 = {
				tempVideoPath: ossRes.src
			};
			that.audioContext.src = ossRes.src;
		},
		// 显示相机
		showCamera(refName) {
			this.$refs[refName]?.close();
			let videoCtx = uni.createVideoContext(refName + "Video");
			videoCtx.pause();
			this.removeStorage();
			uni.setStorageSync("CameraBoxType", this.mainTabInd + 1);

			// #ifdef H5
			// this.toPage("/cameraBox/cameraBoxWeb/cameraBoxWeb");
			this.toPage("/cameraBox/cameraBox/cameraBox");
			// #endif

			// #ifndef H5
			this.toPage("/cameraBox/cameraBox/cameraBox");
			// #endif
		},
		// 清除缓存
		removeStorage() {
			uni.removeStorageSync("CameraBoxType");
			uni.removeStorageSync("tempRecordVideoRes1");
			uni.removeStorageSync("tempRecordVideoRes2");
			uni.removeStorageSync("tempRecordVideoRes3");
		},
		// 跳转页面
		toPage(path, type = "navigateTo") {
			uni[type]({
				url: path
			});
		},

		// 回退
		back() {
			let pages = getCurrentPages();
			if (pages.length > 1) {
				uni.navigateBack({
					delta: 1
				});
			} else {
				uni.setStorageSync("toHome", {
					footerBarListAc: 2
				});
				uni.reLaunch({
					url: "/pages/index/index"
				});
			}
		}
	},
	computed: {
		// 秒数转时间
		seconds2time() {
			return (index_num) => {
				// tools.seconds2time;
				if (!index_num) return "00:00";
				let getHours = (parseInt(index_num / 60 / 60) % 12).toString().padStart(2, 0);
				// let getMinutes = (parseInt(index_num / 60)% 60).toString().padStart(2, 0);
				let getMinutes = parseInt(index_num / 60)
					.toString()
					.padStart(2, 0);
				let getSeconds = (index_num % 60).toFixed(0);
				if (getSeconds < 10) getSeconds = "0" + getSeconds;
				// let str = `${getHours}.${getMinutes}.${getSeconds}`;
				let str = `${getMinutes}:${getSeconds}`;
				return str;
			};
		}
	},
	watch: {
		["successRes2.tempVideoPath"](val) {
			if (val) {
				this.getAudioTime(val);
				if (this.audioContext) {
					this.audioContext.destroy();
					this.audioContext = null;
				}
				this.initAudioContext();
				this.audioContext.src = val;
				this.audioCurrentTime = 0;
			} else {
				if (this.audioContext) {
					this.audioContext.stop();
					this.recordingName = "";
				}
			}
		}
	},
	components: {
		// #ifdef H5
		RecorderCore
		// #endif
	},
	onResize(res) {
		res.size.windowWidth; // 新的显示区域宽度
		res.size.windowHeight; // 新的显示区域高度
		console.log("新的显示区域", res.size.windowWidth, res.size.windowHeight);
	},
	onLoad() {
		this.initSystemInfo();
		this.initAudioContext();
		this.initRecorderManager();
	},
	onShow() {
		this.initRes();
	},
	onHide() {
		this.audioContext.pause();
	},
	onUnload() {
		this.removeStorage();
	}
};
</script>

<style lang="scss">
.MakeAvatar {
	width: 100vw;
	// height: 100vh;
	// background: rgba(7, 7, 9, 1);
	color: #fff;
	font-size: 32rpx;
	position: relative;
	overflow: hidden;
	display: flex;
	flex-direction: column;

	.bgi {
		position: absolute;
		z-index: -1;
		width: 100%;
		height: 100%;
		top: 0vw;
		left: 0vw;
	}

	.title-box {
		display: flex;
		justify-content: space-between;
		align-items: center;
		box-sizing: border-box;
		padding: 0vw 2vw;
		.left {
			flex: 1;
			.back {
				width: 6vw;
			}
		}

		.title {
			flex: 1;
			text-align: center;
			font-size: 36rpx;
			font-weight: 400;
			color: rgba(255, 255, 255, 1);
		}
		.right {
			flex: 1;
			display: flex;
			justify-content: flex-end;
		}
	}

	.main-tabbar {
		margin-top: 2vw;
		display: flex;
		.tabbar-item {
			flex: 1;
			display: flex;
			align-items: center;
			justify-content: center;
			.img {
				width: 23%;
				margin-right: 1vw;
				position: relative;
				display: flex;
				align-items: center;
				justify-content: center;
				.icon {
					width: 100%;
					position: relative;
					// &.ac {
					// 	position: absolute;
					// 	top: 0;
					// 	left: 0;
					// }
				}
			}
			.text {
				font-size: 4.6vw;
				display: flex;
				align-items: center;
				justify-content: center;
				height: 100%;
				line-height: 4.6vw;
				&.ac {
					color: #1afa29;
				}
			}
		}
	}

	.page1,
	.page2 {
		flex: 1;
		width: 90%;
		margin: 3vw auto;
		display: flex;
		flex-direction: column;
		justify-content: center;
		// align-items: center;
		.title {
			margin-top: 5vw;
			margin-bottom: 3vw;
			.titleText {
				color: #fff;
				font-size: 4vw;
				margin-bottom: 3vw;
			}
			.subTitle {
				color: rgba(255, 255, 255, 0.68);
				font-size: 3.5vw;
			}
		}

		.content {
			background: #222224;
			border-radius: 2.5vw;
			overflow: hidden;
			width: 100%;
			flex: 1;
			display: flex;
			flex-direction: column;
			justify-content: center;
			align-items: center;
			background: rgba(255, 255, 255, 0.08);
			border: 1px solid rgba(56, 108, 92, 1);
			backdrop-filter: blur(26px);

			.read-text {
				width: 100%;
				flex: 1;
				box-sizing: border-box;
				padding: 4vw;
				font-size: 4.6vw;
				color: #fff;
				font-weight: 400;
				color: rgba(255, 255, 255, 1);
			}
			.btns {
				width: 100%;
				display: flex;
				box-sizing: border-box;
				padding: 4vw;
				.btn {
					border: 1px solid #fff;
					border-radius: 2vw;
					display: flex;
					justify-content: center;
					align-items: center;
					box-sizing: border-box;
					padding: 1.5vw 2vw;
					margin-right: 1vw;
					.icon {
						width: 3.6vw;
						height: 3.6vw;
						display: block;
						.pic {
							width: 100%;
							height: 100%;
							display: block;
						}
					}
					.txt {
						color: #fff;
						font-size: 4vw;
					}
				}
			}

			.icon {
				width: 23%;
			}
			.text {
				font-size: 3.5vw;
				color: #999;
				font-weight: 400;
				color: rgba(255, 255, 255, 1);
			}
			.video {
				width: 100%;
				height: 100%;
			}
		}
		.record-box {
			display: flex;
			flex-direction: column;
			align-items: center;
			justify-content: flex-end;
			flex: 1;
			.fft {
			}
			.audio-box {
				width: 96%;
				margin: 2vw auto;
				position: relative;
				border-radius: 2.5vw;
				background: #313133;
				display: flex;
				flex-direction: column;
				justify-content: center;
				align-items: center;
				box-sizing: border-box;
				padding: 2.5vw;

				.audio-cont {
					width: 100%;
					display: flex;
					justify-content: center;
					align-items: center;
					.info {
						flex: 1;
						font-size: 3.5vw;
						.name {
							color: #fff;
							margin-bottom: 1vw;
						}
						.time {
							color: rgba(255, 255, 255, 1);
						}
					}
					.btns {
						display: flex;
						justify-content: center;
						align-items: center;
						.item {
							width: 8.6vw;
							margin-right: 2vw;
							&.del {
								width: 6.8vw;
							}
							.icon {
								width: 100%;
								display: block;
							}
						}
					}
				}

				.rate-box {
					margin-top: 5vw;
					width: 100%;
				}
			}

			.time {
				width: max-content;
				box-sizing: border-box;
				padding: 2vw 1.5vw;
				position: relative;
				color: #fff;
				background: rgba(126, 126, 126, 0.386);
				border-radius: 1.5vw;
				margin-bottom: 2vw;
			}
			.record {
				--record-size: 20vw;
				position: relative;
				border-radius: 50%;
				display: flex;
				justify-content: center;
				align-items: center;
				width: var(--record-size);
				height: var(--record-size);
				// border: 1vw solid #fff;
				box-sizing: border-box;

				.box-fff {
					position: absolute;
					transition: all 520ms;
					border-radius: 50%;
					background: rgba(255, 255, 255, 1);
					width: 0%;
					height: 0%;
				}

				.record-btn {
					position: absolute;
					transition: all 520ms;
					border-radius: 50%;
					background: rgba(254, 50, 77, 1);
					width: 86%;
					height: 86%;
				}

				.circle-progress {
					width: 100%;
					height: 100%;
					box-sizing: border-box;
					position: absolute;
					left: 0vw;
					top: 0vw;

					.circle-progress-outer {
						position: absolute;
						top: 0;
						left: 0;
						width: 100%;
						height: 100%;
						border-radius: 50%;
						box-sizing: border-box;
						/* 外圆边框 */
						border: 1vw solid rgba(255, 255, 255, 1);
						/* 裁剪为圆形 */
						clip-path: circle(50% at 50% 50%);
					}

					.left {
						position: absolute;
						top: 0;
						left: 0;
						width: 50%;
						height: 100%;
						overflow: hidden;
					}

					.right {
						position: absolute;
						top: 0;
						left: 50%;
						width: 50%;
						height: 100%;
						overflow: hidden;
					}

					.circle-progress-fill {
						width: 200%;
						height: 100%;
						box-sizing: border-box;
						border: 1vw solid #ff0000;
						position: absolute;
						border-radius: 50%;
						/* 填充背景 */
						/* 裁剪为较小的圆形 */
					}

					.left .circle-progress-fill {
						clip-path: polygon(0% 0%, 50% 0%, 50% 100%, 0% 100%);
						// transform: rotate(180deg);
						left: 0;
						// animation: rotate1 calc(var(--time) / 2) linear forwards calc(var(--time) / 2);
					}

					.right .circle-progress-fill {
						clip-path: polygon(50% 0%, 100% 0%, 100% 100%, 50% 100%);
						transform: rotate(180deg);
						right: 0;
						// animation: rotate1 calc(var(--time) / 2) linear forwards;
					}
				}
			}
		}
		.main-btns {
			display: flex;
			justify-content: space-between;
			align-items: center;
			width: 100%;
			.btn {
				flex: 1;
				display: flex;
				justify-content: center;
				align-items: center;
				height: 15vw;
				margin: 5.2vw 0vw;
				border-radius: 2.5vw;
				font-weight: bold;
				&:nth-child(1) {
					margin-right: 1vw;
				}
			}
			.style1 {
				background: #313133;
				color: #fff;
			}
			.next-btn {
				background: linear-gradient(180deg, #6edc9a 0%, #05ecbd 100%);
				color: #000;
				margin-left: 1vw;
			}
		}
	}

	.page3 {
		flex: 1;
		width: 90%;
		margin: 3vw auto;
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;

		.main-form {
			flex: 1;
			overflow: auto;
			width: 100%;
			display: flex;
			flex-direction: column;

			.form-item {
				margin: 3vw 0vw;
				&.flex-box {
					display: flex;
					flex-direction: column;
				}
				.label {
					font-weight: 400;
					color: rgba(255, 255, 255, 1);
					display: flex;
					align-items: end;

					.text {
						font-size: 36rpx;
						margin-right: 2vw;
					}

					.subText {
						font-size: 24rpx;
						color: #f00;
					}
				}

				.box {
					margin-top: 2.5vw;
					border-radius: 3vw;
					background: rgba(255, 255, 255, 0.08);
					border: 1px solid rgba(56, 108, 92, 1);
					backdrop-filter: blur(26px);
					min-height: 10vw;
					box-sizing: border-box;
					padding: 1vw 2.5vw;

					.text {
						font-size: 28rpx;
						font-weight: 400;
						color: rgba(255, 255, 255, 1);

						&.nac {
							color: rgba(255, 255, 255, 0.46);
						}
					}

					&.input-box {
						display: flex;
						align-items: center;
						height: 6.8vh;
						width: 100%;

						.text {
							width: 100%;
						}
					}

					&.upload-box {
						display: flex;
						flex-direction: column;
						justify-content: center;
						align-items: center;
						flex: 1;
						width: 100%;
						.icon {
							width: 23%;
						}
						.text {
							font-size: 3.5vw;
						}
						.video {
							width: 100%;
							height: 100%;
						}
					}
				}
			}
		}

		.main-btns {
			display: flex;
			justify-content: space-between;
			align-items: center;
			width: 100%;
			.btn {
				// width: 46.8%;
				flex: 1;
				display: flex;
				justify-content: center;
				align-items: center;
				height: 15vw;
				margin: 5.2vw 0vw;
				border-radius: 2.5vw;
				font-weight: bold;
				&:nth-child(1) {
					margin-right: 1vw;
				}
			}
			.style1 {
				background: #313133;
				color: #fff;
			}
			.style2 {
				background: linear-gradient(180deg, #6edc9a 0%, #05ecbd 100%);
				color: #000;
				margin-left: 1vw;
			}
		}
	}

	.popup-view {
		.popup-title {
			padding-top: 5vw;
			color: #fff;
			text-align: center;
		}
		.popup-cont {
			// height: 70vh;
			height: auto;
			overflow: auto;
			box-sizing: border-box;
			padding: 0vw 6vw;
			.title {
				margin-top: 5vw;
				margin-bottom: 3vw;
				.titleText {
					color: #fff;
					font-size: 4vw;
					margin-bottom: 3vw;
				}
				.subTitle {
					color: rgba(255, 255, 255, 0.68);
					font-size: 3.5vw;
				}
			}
			.photo-box {
				display: flex;
				justify-content: space-between;
				align-items: center;
				.pos-box {
					width: 68%;
					position: relative;
					margin: 5vw auto;
					border-radius: 2vw;
					overflow: hidden;
				}
				.pic {
					border-radius: 2vw;
					width: 20vw;
					height: 20vw;
					&.style2 {
						width: 100%;
						display: block;
					}
				}
				.pos-text {
					text-align: center;
					position: absolute;
					width: 100%;
					left: 0vw;
					bottom: 0vw;
					background: rgba(0, 0, 0, 0.68);
					display: flex;
					justify-content: center;
					align-items: center;
					box-sizing: border-box;
					padding: 2vw;
					font-size: 3vw;
					color: #fff;
				}
			}
			.video-box {
				position: relative;
				margin-top: 5vw;
				width: 100%;
				border-radius: 2.5vw;
				overflow: hidden;

				.video {
					width: 100%;
				}
			}
		}

		.popup-btns {
			display: flex;
			justify-content: space-between;
			align-items: center;
			width: 100%;
			box-sizing: border-box;
			padding: 0vw 2vw;
			.btn {
				// width: 46.8%;
				flex: 1;
				display: flex;
				justify-content: center;
				align-items: center;
				height: 15vw;
				margin: 5.2vw 0vw;
				border-radius: 2.5vw;
				font-weight: bold;
				&:nth-child(1) {
					margin-right: 1vw;
				}
			}
			.style1 {
				background: #313133;
				color: #fff;
			}
			.style2 {
				background: linear-gradient(180deg, #6edc9a 0%, #05ecbd 100%);
				color: #000;
				margin-left: 1vw;
			}
		}
		.people-subBtn {
			display: flex;
			justify-content: center;
			align-items: center;
			background: linear-gradient(180deg, #6edc9a 0%, #05ecbd 100%);
			width: 90%;
			height: 15vw;
			margin: 5.2vw auto;
			border-radius: 2.5vw;
			color: #000;
			font-weight: bold;
		}
	}

	.uploadTips {
		display: flex;
		flex-direction: column;
		color: #000;
		font-size: 3.5vw;
	}
}
</style>
